import argparse, sys, random, socket, threading, zen_utils
from concurrent.futures import ThreadPoolExecutor


def client(paras):
     address, requests = paras
     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     sock.connect(address)

     aphorisms = list(zen_utils.aphorisms)
     for i in range(requests):
          for aphorism in random.sample(aphorisms, 3):
               sock.sendall(aphorism)
               print(threading.current_thread().name 
, aphorism, zen_utils.recv_until(sock, b'.'))
               
     sock.close()
        
def run_test(address, concurrency, total_request):
     each_thread_request = (total_request + concurrency - 1) // concurrency
     with ThreadPoolExecutor(max_workers=concurrency) as pool:
          results = list(pool.map(client, [(address, each_thread_request)] * concurrency))
          print('total threads:', len(results))
               
     
def parse_command_args():
     parser = argparse.ArgumentParser(description='network io model performance test')
     parser.add_argument('host', help='IP or hostname')
     parser.add_argument('-p', metavar='port', help='tcp port (default 1060)', type=int, default=1060)
     parser.add_argument('-c', help='concurrency', type=int, default=1)
     parser.add_argument('-n', help='requests', type=int, default=1)

     args = parser.parse_args()
     if (args.c > args.n):
          print('error!! the requests {} is less than concurrency {}'.format(args.n, args.c))
          sys.exit(1)
     address = (args.host, args.p)
     return (address, args.c, args.n)


if __name__ == '__main__':
     address, c, n = parse_command_args()
     run_test(address, c, n)
     print('done!')
     
